#pragma once

#include <stdint.h>
#include <stdbool.h>
#include "hrd_object_movement.h"
#include "hrd_bitmask_definiation.h"

#define MAX_OBJECT_NUMBER (HRD_BITMASK_LIST_LENGTH - 1)

typedef struct hrd_object_allowance_s {
    uint8_t allowed_directions_number;
    hrd_object_move_direction_et allowed_directions[MAX_MOVEMENT_NUMBER];
} hrd_object_allowance_t;

typedef struct hrd_problem_s {
    hrd_bitmask_t goal;
    uint8_t object_number;
    hrd_bitmask_list_t bitmask_list;
    hrd_object_allowance_t object_allowance_list[MAX_OBJECT_NUMBER];
} hrd_problem_t;

typedef struct hrd_action_s {
    uint8_t object_index;
    hrd_object_move_direction_et direction;
    uint8_t length;
} hrd_action_t;


hrd_problem_t *HrdCore_LoadProblem(char *filename);

void HrdCore_DestroyProblem(hrd_problem_t *hrd_problem);

bool HrdCore_IsGoalAchieved(hrd_problem_t *hrd_problem);

typedef enum hrd_take_action_ret_e {
    ACTION_TOOK,
    NO_SUCH_OBJECT,
    ACTION_NOT_ALLOWED,
    ACTION_CANNOT_BE_DONE
} hrd_take_action_ret_et;

hrd_take_action_ret_et HrdCore_TakeAction(hrd_problem_t *hrd_problem, hrd_action_t action);

void HrdCore_ShowColorMapping(hrd_problem_t *hrd_problem);

void HrdCore_DisplayMapInColorizeBlock(hrd_problem_t *hrd_problem, bool show_grid);

void HrdCore_DisplayMapInCharacter(hrd_problem_t *hrd_problem, bool show_grid);

uint8_t HrdCore_SolveProblem(hrd_problem_t *hrd_problem, hrd_action_t *solution);